package com.example.controller;

import com.example.common.Result;
import com.example.config.MinioConfig;
import com.example.dto.FileUploadDTO;
import com.example.exception.BusinessException;
import com.example.service.MinioService;
import com.example.utils.MinioUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;

/**
 * 文件上传控制器
 * 处理图片等文件的上传功能，使用MinIO对象存储
 */
@Slf4j
@RestController
@RequestMapping("/api/upload")
public class FileUploadController {

    @Autowired
    private MinioService minioService;

    @Autowired
    private MinioConfig minioConfig;

    // 允许的图片文件类型
    private static final String[] ALLOWED_IMAGE_TYPES = {
        "image/jpeg", "image/jpg", "image/png", "image/gif", "image/bmp", "image/webp"
    };

    // 最大文件大小 (5MB)
    private static final long MAX_FILE_SIZE = 5 * 1024 * 1024;

    /**
     * 上传图片文件
     */
    @PostMapping("/image")
    public Result<FileUploadDTO> uploadImage(@RequestParam("file") MultipartFile file) {
        try {
            log.info("开始上传图片到MinIO: {}, 大小: {} bytes", file.getOriginalFilename(), file.getSize());
            
            // 验证文件
            validateImageFile(file);
            
            // 上传到MinIO
            String objectName = minioService.uploadFile(file, "images");
            String fileUrl = minioService.getFileUrl(objectName);
            
            // 构建返回数据
            FileUploadDTO result = new FileUploadDTO();
            result.setFileName(extractFileName(objectName));
            result.setOriginalName(file.getOriginalFilename());
            result.setFilePath(objectName);
            result.setFileUrl(fileUrl);
            result.setFileSize(file.getSize());
            result.setContentType(file.getContentType());
            
            log.info("图片上传到MinIO成功: {} -> {}", file.getOriginalFilename(), objectName);
            
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("图片上传到MinIO失败: {}", file.getOriginalFilename(), e);
            if (e instanceof BusinessException) {
                throw e;
            }
            throw BusinessException.fileUploadFailed();
        }
    }

    /**
     * 删除图片文件
     */
    @DeleteMapping("/image")
    public Result<String> deleteImage(@RequestParam("filePath") String filePath) {
        try {
            if (filePath == null || filePath.trim().isEmpty()) {
                return Result.success("删除成功");
            }
            
            // 如果传入的是完整URL，提取对象名
            String objectName = MinioUtils.extractObjectNameFromUrl(filePath, minioConfig.getBucketName());
            
            // 从MinIO删除文件
            minioService.deleteFile(objectName);
            
            log.info("图片从MinIO删除成功: {} -> {}", filePath, objectName);
            return Result.success("删除成功");
            
        } catch (Exception e) {
            log.error("从MinIO删除图片失败: {}", filePath, e);
            // 删除失败不抛异常，因为这不是关键操作
            return Result.success("删除成功");
        }
    }

    /**
     * 验证图片文件
     */
    private void validateImageFile(MultipartFile file) {
        // 检查文件是否为空
        if (file == null || file.isEmpty()) {
            throw BusinessException.dataValidationFailed("请选择要上传的文件");
        }
        
        // 检查文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            throw BusinessException.fileSizeExceeded();
        }
        
        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !Arrays.asList(ALLOWED_IMAGE_TYPES).contains(contentType.toLowerCase())) {
            throw BusinessException.fileTypeNotSupported();
        }
        
        // 检查文件名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            throw BusinessException.dataValidationFailed("文件名不能为空");
        }
    }

    /**
     * 从对象名中提取文件名
     */
    private String extractFileName(String objectName) {
        if (objectName == null || objectName.lastIndexOf('/') == -1) {
            return objectName;
        }
        return objectName.substring(objectName.lastIndexOf('/') + 1);
    }
} 